/**
 * 动态创建可执行对象
 * @param fn
 * @param names
 * @returns {*}
 */
const node = (fn, paths)=>{

    if(!Array.isArray(paths)){
        paths = paths ? [paths] : [];
    }
    const noop = function (...args){
        return fn(paths, ...args);
    };
    return new Proxy(noop, {
        get(target, key, receiver){
            //'constructor', 'prototype', 'call', 'apply', 'bind', 'name', 'length', 'caller', 'arguments', inspect
            if( typeof key === 'symbol' ){
                return Reflect.get(target, key, receiver)
            }

            if(paths.length > 9999){
                return null
            }
            return node(fn, [...paths, key.replace(/^\//g, '')]);;
        }
    })
};


export const fn = async (url, ...params) => {

    let options = typeof url == 'object' ? url : {url};
    let method = options.method || 'POST';

    //如果是GET请求，将参数拼接到URL上 注意：GET请求的参数args是一个数组
    if(method.toLowerCase() === 'get'){
      let query = [];
      params.map((item, index)=>{
        query.push(`args=${item}`)
      });
      options.url = `${options.url}?${query.join('&')}`;
    }

    let apiUrl = `${options.url}`;
    try{
      let response = await fetch(apiUrl, {
        // mode: 'cors',
        method,
        credentials: "include",
        headers: {
          'Content-Type': 'application/json'
        },
        body: method.toLowerCase() == 'post' ? JSON.stringify({
          args:[...params]   //args是中间件默认约定的字段
        }) : null
      });
      let data = await response.json();
      // console.log(`response from:${url}:`, data)
      return data;
    }catch(e){
      console.error(`请求${apiUrl}发生错误`,e)
      throw e; 
    }
};

export default (config)=>{
    let host = config.host || 'http://localhost';
    let root = config.root || '';
    let method = config.method || 'POST';

    return node((paths, ...args)=>{
        let path = paths.join('/');
        return fn({
          method,
          url: `${host}/${root? '/'+root: ''}${path}`
        }, ...args)
    });
}